/*
frigOS
Licensed under GPLv3
*/

#ifndef DISABLE_BUTTONS

#include "button.h"
#include "kernel.h"
#include "led.h"
#include "serial.h"
#include <avr/interrupt.h>

#define EIFR_BUTTON     ((1 << INT4) | (1 << INT5) | (1 << INT6) | (1 << INT7))
#define EIMSK_BUTTON    ((1 << INTF4) | (1 << INTF5) | (1 << INTF6) | (1 << INTF7))

uint8_t debounce_values[5];

// initialize the buttons;
// set pins as inputs and enable interrupts
void initButtons()
{

    // set data direction to input (0)
    // Start Button is on port D, others on port E
    DDRE &= ~ DDR_UP_BUTTON;
    DDRE &= ~ DDR_DOWN_BUTTON;
    DDRE &= ~ DDR_LEFT_BUTTON;
    DDRE &= ~ DDR_RIGHT_BUTTON;
    //DDRD &= ~ DDR_START_BUTTON;

    // buttons initially not pressed
    PORTE |= PIN_UP_BUTTON;
    PORTE |= PIN_DOWN_BUTTON;
    PORTE |= PIN_LEFT_BUTTON;
    PORTE |= PIN_RIGHT_BUTTON;
    //PORTD |= PIN_START_BUTTON;


    // disable external interrupts when button is pushed
    EIFR &= ~EIFR_BUTTON;
    EIMSK &= ~EIMSK_BUTTON;

    // enable external interrupts when button is pushed
    //EIFR |= EIFR_BUTTON;
    //EIMSK |= EIMSK_BUTTON;

    // TODO: interrupts for Start button (?)
}

// manage button debouncing the buttons
uint8_t monitorButtons()
{
    uint8_t pollResult;
    uint8_t i;

    pollResult = pollButtons();

    for(i=0; i<5; i++)
    {
        if(pollResult & (1 << i))
        {
            debounce_values[i]++;
        }

        if(debounce_values[i] >= DEBOUNCE_LIMIT)
        {
            debounce_values[i] = 0;

            switch((1<<i))
            {
                case UP_BUTTON:
                    fireEvent(UP_BUTTON_PRESSED_EVENT);
                    break;

                case DOWN_BUTTON:
                    fireEvent(DOWN_BUTTON_PRESSED_EVENT);
                    break;

                case RIGHT_BUTTON:
                    fireEvent(RIGHT_BUTTON_PRESSED_EVENT);
                    break;

                case LEFT_BUTTON:
                    fireEvent(LEFT_BUTTON_PRESSED_EVENT);
                    break;

                //case START_BUTTON:
                //    fireEvent(START_BUTTON_PRESSED_EVENT);
                //    break;

                default:
                    break;
            }
        }
    }

    return pollResult;
}

// fire an event if the appropriate button has been pressed or not
// to deal with debouncing each button has a counter that is incremented
// every time this ISR is fired and the pin is on
// the event fires once when the threshold is reached
// this should prevent the event from firing repeatedly if the button is held

ISR(INT4_vect)
{
    fireEvent(UP_BUTTON_PRESSED_EVENT);
}
ISR(INT5_vect)
{
    fireEvent(DOWN_BUTTON_PRESSED_EVENT);
}
ISR(INT6_vect)
{
    fireEvent(LEFT_BUTTON_PRESSED_EVENT);
}
ISR(INT7_vect)
{
    fireEvent(RIGHT_BUTTON_PRESSED_EVENT);
}
//ISR(???_vect)
//{
//    fireEvent(START_BUTTON_PRESSED_EVENT);
//}

#endif
